/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "dhfwk_publisher_test.h"

#include <cstdint>
#include <iostream>
#include <map>

#include "dh_utils_tool.h"

using OHOS::DistributedHardware::DHTopic;

namespace OHOS {
namespace DistributedHardware {
namespace {
    const int32_t RANDOM_MSG_NUM = 100;
    const uint32_t TOPIC_NUM_MAX = 5;
    DHTopic DHTOPICS[] = {
        DHTopic::TOPIC_MIN,
        DHTopic::TOPIC_START_DSCREEN,
        DHTopic::TOPIC_SINK_PROJECT_WINDOW_INFO,
        DHTopic::TOPIC_STOP_DSCREEN,
        DHTopic::TOPIC_DEV_OFFLINE,
        DHTopic::TOPIC_MAX,
    };
    std::map<DHTopic, std::string> TOPIC_DESC = {
        { DHTopic::TOPIC_MIN, "TOPIC_MIN" },
        { DHTopic::TOPIC_START_DSCREEN, "TOPIC_START_DSCREEN" },
        { DHTopic::TOPIC_SINK_PROJECT_WINDOW_INFO, "TOPIC_SINK_PROJECT_WINDOW_INFO" },
        { DHTopic::TOPIC_STOP_DSCREEN, "TOPIC_STOP_DSCREEN" },
        { DHTopic::TOPIC_DEV_OFFLINE, "TOPIC_DEV_OFFLINE" },
        { DHTopic::TOPIC_MAX, "TOPIC_MAX" }
    };

    std::map<Role, std::string> ROLE_DESC = {
        { Role::PUBLISHER, "Publisher" },
        { Role::LISTENER, "Listener" }
    };
}

void DHFWKPublisherTest::TestPublisherListener::OnMessage(
    const DHTopic topic, const std::string& message)
{
    int64_t recvTime = GetCurrentTime();
    std::cout << std::endl;
    std::cout << "Receive Message " << std::endl;
    std::cout << "topic::" << TOPIC_DESC[topic] << std::endl;
    std::cout << "message::" << message << std::endl;
    std::cout << "Time: " << recvTime << std::endl;
    std::cout << std::endl;
}

DHFWKPublisherTest::DHFWKPublisherTest(Role role) : role_(role), listenerMap_({})
{
    std::cout << "Start Test Tool As: " << ROLE_DESC[role] << std::endl;
}

DHFWKPublisherTest::~DHFWKPublisherTest()
{
}

DHTopic DHFWKPublisherTest::GetRandomTopic()
{
    uint32_t idx = 0;
    while (idx == 0) {
        idx = rand() % TOPIC_NUM_MAX;
    }

    return DHTOPICS[idx];
}

void DHFWKPublisherTest::PublishRandomMessage()
{
    if (role_ == Role::LISTENER) {
        std::cout << "Role " << ROLE_DESC[role_] << " CAN NOT Publish Random Message" << std::endl;
        return;
    }

    int32_t cnt = 0;
    while (cnt < RANDOM_MSG_NUM) {
        DHTopic topic = GetRandomTopic();
        PublishMessage(topic, "JustForTest");
        cnt++;
    }
}

void DHFWKPublisherTest::PublishMessage(const DHTopic topic, const std::string msg)
{
    if (role_ == Role::LISTENER) {
        std::cout << "Role " << ROLE_DESC[role_] << " CAN NOT Publish Message" << std::endl;
        return;
    }

    int64_t publishTime = GetCurrentTime();
    int32_t ret = dhfwkKit.PublishMessage(topic, msg);
    std::cout << "Publish Message " << std::endl;
    std::cout << "topic: " << TOPIC_DESC[topic] << std::endl;
    std::cout << "message: " << msg << std::endl;
    std::cout << "Time: " << publishTime << std::endl;
    std::cout << "Ret: " << ret << std::endl;
}
void DHFWKPublisherTest::RegisterListener(const DHTopic topic)
{
    if (role_ == Role::PUBLISHER) {
        std::cout << "Role " << ROLE_DESC[role_] << " CAN NOT Register Listener" << std::endl;
        return;
    }

    if (listenerMap_.find(topic) == listenerMap_.end() || listenerMap_[topic] == nullptr) {
        sptr<TestPublisherListener> listener = new TestPublisherListener();
        listenerMap_[topic] = listener;
    }

    int32_t ret = dhfwkKit.RegisterPublisherListener(topic, listenerMap_[topic]);
    std::cout << "Register topic listener, topic: " << TOPIC_DESC[topic] << ", ret: " << ret << std::endl;
}

void DHFWKPublisherTest::UnregisterListener(const DHTopic topic)
{
    if (role_ == Role::PUBLISHER) {
        std::cout << "Role " << ROLE_DESC[role_] << " CAN NOT Unregister Listener" << std::endl;
        return;
    }

    if (listenerMap_.find(topic) == listenerMap_.end()) {
        std::cout << "Not Register topic listener, CAN NOT unregister, topic: " << TOPIC_DESC[topic] << std::endl;
        return;
    }

    int32_t ret = dhfwkKit.UnregisterPublisherListener(topic, listenerMap_[topic]);
    std::cout << "Unregister topic listener, topic: " << TOPIC_DESC[topic] << ", ret: " << ret << std::endl;
}
}
}